package com.ruoyi.project.module.api.pay.alipay.service;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.ExtUserInfo;
import com.alipay.api.domain.ExtendParams;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.ruoyi.project.module.api.pay.alipay.config.AlipayConfig;
import com.ruoyi.project.module.api.pay.common.service.CommonPayService;
import com.ruoyi.project.module.api.utils.RedisUtil;
import com.ruoyi.project.module.common.config.CustomConfig;
import com.ruoyi.project.module.common.dict.AppOrderStatus;
import com.ruoyi.project.module.common.dict.AppPaymentMethod;
import com.ruoyi.project.module.member.domain.Member;
import com.ruoyi.project.module.order.domain.Order;
import com.ruoyi.project.module.order.service.impl.OrderServicePlusImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
public class AlipayService {

    @Autowired
    private OrderServicePlusImpl orderService;

    @Autowired
    private CustomConfig customConfig;

    @Autowired
    private CommonPayService commonPayService;

    @Autowired
    private RedisUtil redisUtil;

    private static final String ORDER_ALIPAY_PREFIX = "order:alipay:";

    /**
     * 创建支付宝订单
     *
     * @param member    当前登录会员
     * @param orderType 订单类型
     * @param feesetId  套餐id
     * @param point     订单类型为积分时候的积分数量
     * @return
     */
    public String createOrder(Member member, String orderType, String feesetId, Integer point) {
        Order order = commonPayService.createCommonOrder(member, orderType, feesetId, point);
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        String outTradeNo = snowflake.nextIdStr();
        order.setOutTradeNo(outTradeNo);
        order.setPaymentMethod(AppPaymentMethod.D_2_ZFB);

        String key = ORDER_ALIPAY_PREFIX + outTradeNo;
        JSONObject order_json = JSONUtil.parseObj(order, false, true);
        redisUtil.set(key, order_json.toString(), AlipayConfig.qrCodeTimeoutExpress * 60);
        return key;
    }

    /**
     * 创建支付二维码
     *
     * @param orderKey
     * @return
     * @throws AlipayApiException
     */
    public String createCode(String orderKey) throws AlipayApiException {
        Assert.notBlank(orderKey, "订单不存在");
        String order_json = (String) redisUtil.get(orderKey);
        Order order = JSONUtil.toBean(order_json, Order.class);

        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.serverUrl, AlipayConfig.appId, AlipayConfig.privateKey, "json", "utf-8", AlipayConfig.alipayPublicKey, AlipayConfig.signType);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); //创建API对应的request类
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setOutTradeNo(order.getOutTradeNo());
        model.setTotalAmount(order.getTotalPrice() + "");
        model.setSubject(order.getOrderSubject() + order.getOutTradeNo());
        model.setQrCodeTimeoutExpress(AlipayConfig.qrCodeTimeoutExpress.toString() + AlipayConfig.qrCodeTimeoutExpressUnit);
        request.setBizModel(model);
        //支付宝异步通知地址
        request.setNotifyUrl(customConfig.getBaseUrl() + AlipayConfig.notifyUrl);
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        return response.getQrCode();
    }

    /**
     * 处理支付宝回调
     *
     * @param tradeStatus
     * @param outTradeNo
     * @param tradeNo
     */
    @Transactional
    public void dealOrder(String tradeStatus, String outTradeNo, String tradeNo) {

        Order order = orderService.selectOrderByOutTradeNo(outTradeNo);
        if (null == order) {
            String orderKey = ORDER_ALIPAY_PREFIX + outTradeNo;
            String order_json = (String) redisUtil.get(orderKey);
            order = JSONUtil.toBean(order_json, Order.class);
            order.setOrderSubject(order.getOrderSubject() + outTradeNo);
        }

        if ("TRADE_SUCCESS".equals(tradeStatus)) {
            order.setOrderStatus(AppOrderStatus.D_1_FKCG);
            order.setPaymentTime(new Date());
            order.setTradeNo(tradeNo);
            commonPayService.dealPaySuccess(order);
        } else if ("WAIT_BUYER_PAY".equals(tradeStatus)) {
            order.setOrderStatus(AppOrderStatus.D_0_WFK);
            order.setPaymentTime(new Date());
            order.setTradeNo(tradeNo);
        } else {
            order.setOrderStatus(AppOrderStatus.D_2_FKSB);
            order.setPaymentTime(new Date());
            order.setTradeNo(tradeNo);
        }
        if (null == order.getId()) {
            orderService.insertOrder(order);
        } else {
            orderService.updateOrder(order);
        }
    }

}
